
#include <memory.h>

#define LAND_GRAPHICS_CORE

#include "init.h"
#include "land_math.h"


static struct {
	LandGraphics* config;
	LandVertexBackend* backend;
}ctx = { 0 };

int
landInitVertexContext(LandGraphics* config, LandVertexBackend* backend) {
	ctx.config = config;
	ctx.backend = backend;
	return 0;
}

static void
freeVertex(LandRef* ref) {
	LandVertex* vertex = (LandVertex*)ref;
	ctx.backend->freeVertex(vertex);
}

LAND_GRAPHICS_API LandVertex*
landNewVertex(unsigned cap){
	size_t size = ctx.backend->sizeofVertex();
	LandVertex* vertex = landNewRef(size, freeVertex);
	vertex->indexs = landNewList(sizeof(unsigned), cap * 2);
	vertex->points = landNewList(sizeof(LandPoint), cap);
	ctx.backend->newVertex(vertex, cap);
	return vertex;
}

LAND_GRAPHICS_API void
landClearVertex(LandVertex* vertex) {
	landClearList(vertex->indexs);
	landClearList(vertex->points);
	//ctx.backend->clearVertex(vertex);
}

LAND_GRAPHICS_API void
landClearVertexCap(LandVertex* vertex) {
	landClearListCap(vertex->indexs);
	landClearListCap(vertex->points);
	//ctx.backend->clearVertexCap(vertex);
}

LAND_GRAPHICS_API void
landPushVertexPoints(
	LandVertex* vertex, LandPoint* points, unsigned count) {
	landPushList(vertex->points, points, count);
}
LAND_GRAPHICS_API void
landPushVertexIndex(LandVertex* vertex,
	unsigned* indexs, unsigned count) {
	landPushList(vertex->indexs, indexs, count);
}

LAND_GRAPHICS_API void
landUploadVertex(LandVertex* vertex) {
	ctx.backend->uploadVertex(vertex);
	landClearVertex(vertex);
}

LAND_GRAPHICS_API unsigned
landPushVertexRect(LandVertex* vertex,
	LandVector* rect, LandVector* uv,
	LandVector* color, unsigned* offset, LandMatrix* transform) {
	LandPoint points[] = {
		{
			rect->left, rect->top, 0.f, 1.f,
			uv->left, uv->top, 0.f, 0.f,
			color->r, color->g, color->b, color->a,
			0.f, 0.f, 1.f, 1.f,
		},{
			rect->left, rect->bottom, 0.f, 1.f,
			uv->left, uv->bottom, 0.f, 0.f,
			color->r, color->g, color->b, color->a,
			0.f, 0.f, 1.f, 1.f,
		},{
			rect->right, rect->top, 0.f, 1.f,
			uv->right, uv->top, 0.f, 0.f,
			color->r, color->g, color->b, color->a,
			0.f, 0.f, 1.f, 1.f,
		},{
			rect->right, rect->bottom, 0.f, 1.f,
			uv->right, uv->bottom, 0.f, 0.f,
			color->r, color->g, color->b, color->a,
			0.f, 0.f, 1.f, 1.f,
		},
	};
	unsigned indexs[] = { 0, 1, 2, 1, 2, 3 };
	if (transform) {
		for (unsigned i = 0; i < 4; i++) {
			landVectorMulMatrix(&points[i].position, transform);
		}
	}
	if (offset) {
		for (unsigned i = 0; i < 6; i++) {
			indexs[i] += *offset;
		}
		*offset += 4;
	}
	landPushList(vertex->points, points, 4);
	landPushList(vertex->indexs, indexs, 6);
	return 6;
}